package org.abratuhi.kvngroupware.client;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;

import org.abratuhi.kvngroupware.gui.GUIJokeManager;
import org.abratuhi.kvngroupware.gui.GUILogin;
import org.abratuhi.kvngroupware.gui.GUIMain;
import org.abratuhi.kvngroupware.gui.GUIRegistration;
import org.abratuhi.kvngroupware.model.Brainstorm;
import org.abratuhi.kvngroupware.model.Chatroom;
import org.abratuhi.kvngroupware.model.Joke;
import org.abratuhi.kvngroupware.model.League;
import org.abratuhi.kvngroupware.model.Scenario;
import org.abratuhi.kvngroupware.model.Team;
import org.abratuhi.kvngroupware.model.User;
import org.abratuhi.kvngroupware.network.C_Client;
import org.abratuhi.kvngroupware.network.Message;
import org.jdom.Element;

public class KVNGroupwareClient {
	
	public final static String localeFile = "locale.xml";
	public final static String clientFile = "client.properties";
	
	public Properties locale;
	public Properties clientprops;
	
	User user = new User();
	Team team = new Team();
	
	ArrayList<Brainstorm> brainstorms = new ArrayList<Brainstorm>();
	ArrayList<Chatroom> chatrooms = new ArrayList<Chatroom>();
	ArrayList<Joke> jokes = new ArrayList<Joke>();
	ArrayList<Scenario> scenarios = new ArrayList<Scenario>();
	ArrayList<League> leagues = new ArrayList<League>();
	
	C_Client netclient;
	ClientMPTUA mptua;
	
	GUILogin guilogin;
	GUIRegistration guiregistration;
	GUIMain guimain;
	public GUIJokeManager guijokemanager;
	
	String log = new String();
	
	public KVNGroupwareClient(){
		this.locale = loadProperties(localeFile);
		this.clientprops = loadProperties(clientFile);
		this.netclient = new C_Client(this, clientprops.getProperty("client.server.host"), Integer.valueOf(clientprops.getProperty("client.server.port")));
		this.mptua = new ClientMPTUA(this);
		this.guilogin = new GUILogin(this, locale);
		this.guimain = new GUIMain(this, locale);
		this.guiregistration = new GUIRegistration(this, locale);
		this.guijokemanager = new GUIJokeManager(this, jokes, locale);
	}
	
	public User getUser(){
		return this.user;
	}
	public Team getTeam(){
		return this.team;
	}
	public /*synchronized*/ ArrayList<Brainstorm> getBrainstorms(){
		return this.brainstorms;
	}
	public String[] getBrainstormIdsAsArray(){
		String[] ids = new String[brainstorms.size()];
		for(int i=0; i<brainstorms.size(); i++){
			ids[i] = brainstorms.get(i).getId();
		}
		return ids;
	}
	public /*synchronized*/ ArrayList<Chatroom> getChatrooms(){
		return this.chatrooms;
	}
	public String[] getChatroomIdsAsArray(){
		String[] ids = new String[chatrooms.size()];
		for(int i=0; i<chatrooms.size(); i++){
			ids[i] = chatrooms.get(i).getId();
		}
		return ids;
	}
	/*synchronized*/ ArrayList<League> getLeagues(){
		return this.leagues;
	}
	
	public ArrayList<Joke> getJokes(){
		return this.jokes;
	}
	public String[] getJokeIdsAsArray(){
		String[] ids = new String[jokes.size()];
		for(int i=0; i<jokes.size(); i++){
			ids[i] = jokes.get(i).getId();
		}
		return ids;
	}
	
	void setUser(User user){
		this.user = user;
	}
	void setTeam(Team team){
		this.team = team;
	}
	
	// ******************
	// brainstorm section
	// ******************
	synchronized void addBrainstorm(Brainstorm brainstorm){
		getBrainstorms().add(brainstorm);
	}
	synchronized boolean containsBrainstorm(Brainstorm brainstorm){
		return getBrainstorms().contains(brainstorm);
	}
	synchronized boolean containsBrainstorm(String id){
		for(int i=0; i<getBrainstorms().size(); i++){
			if(getBrainstorms().get(i).getId().equals(id)){
				return true;
			}
		}
		return false;
	}
	synchronized Brainstorm getBrainstorm(String id){
		for(int i=0; i<getBrainstorms().size(); i++){
			if(getBrainstorms().get(i).getId().equals(id)){
				return getBrainstorms().get(i);
			}
		}String[] ids = new String[chatrooms.size()];
		for(int i=0; i<chatrooms.size(); i++){
			ids[i] = chatrooms.get(i).getId();
		}
		
		return null;
	}
	synchronized void removeBrainstorm(Brainstorm brainstorm){
		getBrainstorms().remove(brainstorm);
	}
	synchronized void removeBrainstorm(String id){
		for(int i=0; i<getBrainstorms().size(); i++){
			if(getBrainstorms().get(i).getId().equals(id)){
				getBrainstorms().remove(i);
			}
		}
	}
	
	// ****************
	// chatroom section
	// ****************
	synchronized void addChatroom(Chatroom chatroom){
		getChatrooms().add(chatroom);
	}
	synchronized boolean containsChatroom(Chatroom chatroom){
		return getChatrooms().contains(chatroom);
	}
	synchronized boolean containsChatroom(String id){
		for(int i=0; i<getChatrooms().size(); i++){
			if(getChatrooms().get(i).getId().equals(id)){
				return true;
			}
		}
		return false;
	}
	synchronized Chatroom getChatroom(String id){
		for(int i=0; i<getChatrooms().size(); i++){
			if(getChatrooms().get(i).getId().equals(id)){
				return getChatrooms().get(i);
			}
		}
		return null;
	}
	synchronized void removeChatroom(Chatroom chatroom){
		getChatrooms().remove(chatroom);
	}
	synchronized void removeChatroom(String id){
		for(int i=0; i<getChatrooms().size(); i++){
			if(getChatrooms().get(i).getId().equals(id)){
				getChatrooms().remove(i);
			}
		}
	}
	
	// *************
	// jokes section
	// *************
	public void addJoke(Joke joke){
		jokes.add(joke);
	}
	public int indexOf(Joke joke){
		return jokes.indexOf(joke);
	}
	public int indexOf(String jokeId){
		for(int i=0; i<jokes.size(); i++){
			if(jokes.get(i).getId().equals(jokeId)){
				return i;
			}
		}
		return -1;
	}
	public boolean containsJoke(Joke joke){
		return jokes.contains(joke);
	}
	public boolean containsJoke(String jokeId){
		int index = indexOf(jokeId);
		return (index == -1)? true : false;
	}
	public Joke getJoke(String jokeId){
		int index = indexOf(jokeId);
		return (index == -1)? null : jokes.get(index);
	}
	public Joke getJoke(int index){
		return (index != -1)? jokes.get(index) : null;
	}
	public void rateJoke(String jokeId, String rating){
		Joke joke = getJoke(jokeId);
		if(joke != null) joke.setRating(rating);
	}
	public void updateJoke(Joke updatedJoke){
		int index = indexOf(updatedJoke.getId());
		if(index != -1) jokes.set(index, updatedJoke);
	}
	
	// ****************
	// scenario section
	// ****************
	public void addScenario(Scenario scenario){
		scenarios.add(scenario);
	}
	
	public int indexOfScenario(Scenario scenario){
		return scenarios.indexOf(scenario);
	}
	
	public int indexOfScenario(String scenarioId){
		for(int i=0; i<scenarios.size(); i++){
			if(scenarios.get(i).getId().equals(scenarioId)){
				return i;
			}
		}
		return -1;
	}
	
	public boolean containsScenario(Scenario scenario){
		return scenarios.contains(scenario);
	}
	
	public boolean containsScenario(String scenarioId){
		int index = indexOfScenario(scenarioId);
		return index==-1? false : true;
	}
	
	public Scenario getScenario(String scenarioId){
		int index = indexOfScenario(scenarioId);
		return index==-1? null : scenarios.get(index);
	}
	
	public Scenario getScenario(int index){
		return index==-1? null : scenarios.get(index);
	}
	
	public void updateScenario(Scenario updatedScenario){
		int index = indexOfScenario(updatedScenario.getId());
		if(index != -1) scenarios.set(index, updatedScenario);
	}
	
	public int getScenarioNumber(){
		return scenarios.size();
	}
	
	// *****************
	// messaging section
	// *****************
	public void proceedMessage(Message message) {
		System.out.println("Client:\tProceeding message:\t"+message.toString());
		this.mptua.proceedMessage(message);
	}
	
	public Message createMessage(String[] attrNames, String[] attrValues, String text, Element[] content){
		return mptua.createMessage(attrNames, attrValues, text, content);
	}
	
	public void sendMessage(Message message){
		//System.out.println("Client:\tSending message:\t"+message.toString());
		this.netclient.sendMessage(message);
	}
	
	// *********
	// something
	// *********
	public GUILogin getGUILogin(){
		return this.guilogin;
	}
	public GUIRegistration getGUIRegistration(){
		return this.guiregistration;
	}
	public GUIMain getGUIMain(){
		return this.guimain;
	}
	
	public void start(){
		this.netclient.start();
	}
	
	public void stop(){
		this.netclient.stop();
	}
	
	public void exit(){
		System.exit(0);
	}
	
	public Properties loadProperties(String file){
		Properties props = new Properties();
		try {
			if(file.endsWith(".xml")){
		        props.loadFromXML(new FileInputStream(file));
			}
			else if(file.endsWith(".properties") || file.endsWith(".preferences")){
				props.load(new FileInputStream(file));
			}
	    } catch (IOException e) {
	    	e.printStackTrace();
	    }
	    return props;
	}
	
	// ****
	// main
	// ****
	public static void main(String[] args){
		KVNGroupwareClient kvnclient = new KVNGroupwareClient();
		kvnclient.start();
		kvnclient.getGUILogin().createJFrame();
	}

}
